#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量导出对话框
用于选择导出选项和范围
"""

import logging
from datetime import datetime, timedelta
from typing import List, Dict, Any, Optional

from PyQt6.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QGridLayout, QLabel, QPushButton,
    QCheckBox, QComboBox, QSpinBox, QDateEdit, QTimeEdit, QGroupBox, QRadioButton,
    QButtonGroup, QLineEdit, QTextEdit, QProgressBar, QMessageBox,
    QFileDialog, QFormLayout
)
from PyQt6.QtCore import Qt, pyqtSignal, QThread, QTimer
from PyQt6.QtGui import QFont

from src.models.models import Sample
from src.utils.export_manager import ExportManager

logger = logging.getLogger(__name__)

class ExportWorker(QThread):
    """导出工作线程"""
    
    progress_updated = pyqtSignal(int)
    export_completed = pyqtSignal(bool, str)
    
    def __init__(self, export_manager: ExportManager, samples: List[Sample], 
                 file_path: str, export_format: str = "excel", include_all_data: bool = True):
        super().__init__()
        self.export_manager = export_manager
        self.samples = samples
        self.file_path = file_path
        self.export_format = export_format
        self.include_all_data = include_all_data
    
    def run(self):
        """执行导出"""
        try:
            self.progress_updated.emit(10)
            
            if self.export_format == "excel":
                # 执行Excel导出
                success = self.export_manager.export_samples_to_excel(
                    self.samples, self.file_path, self.include_all_data
                )
            elif self.export_format == "pdf":
                # 执行PDF导出
                success = self.export_manager.export_samples_to_pdf_zip(
                    self.samples, self.file_path
                )
            else:
                success = False
                logger.error(f"不支持的导出格式: {self.export_format}")
            
            self.progress_updated.emit(100)
            
            if success:
                format_name = "Excel" if self.export_format == "excel" else "PDF"
                self.export_completed.emit(True, f"{format_name}导出成功: {self.file_path}")
            else:
                format_name = "Excel" if self.export_format == "excel" else "PDF"
                self.export_completed.emit(False, f"{format_name}导出失败")
                
        except Exception as e:
            logger.error(f"导出工作线程失败: {e}")
            self.export_completed.emit(False, f"导出失败: {str(e)}")

class BatchExportDialog(QDialog):
    """批量导出对话框"""
    
    def __init__(self, samples: List[Sample], parent=None, current_page_samples: List[Sample] = None, selected_samples: List[Sample] = None):
        super().__init__(parent)
        self.samples = samples
        self.current_page_samples = current_page_samples or samples
        self.selected_samples = selected_samples or []
        self.export_manager = ExportManager()
        self.export_worker = None
        
        self.init_ui()
        self.load_hospital_info()
    
    def init_ui(self):
        """初始化UI"""
        self.setWindowTitle("批量导出样本数据")
        self.setModal(True)
        self.resize(600, 550)
        
        layout = QVBoxLayout(self)
        layout.setSpacing(10)
        
        # 导出格式组
        format_group = QGroupBox("导出格式")
        format_layout = QVBoxLayout(format_group)
        
        # 格式选择
        self.excel_radio = QRadioButton("Excel格式 (.xlsx)")
        self.excel_radio.setChecked(True)
        self.excel_radio.toggled.connect(self.on_export_format_changed)
        format_layout.addWidget(self.excel_radio)
        
        self.pdf_radio = QRadioButton("PDF格式 (.zip)")
        self.pdf_radio.toggled.connect(self.on_export_format_changed)
        format_layout.addWidget(self.pdf_radio)
        
        # PDF格式说明
        pdf_note = QLabel("PDF格式：每条样本生成独立PDF文件，打包成ZIP压缩文件")
        pdf_note.setStyleSheet("color: #666; font-size: 10px; margin-left: 20px;")
        format_layout.addWidget(pdf_note)
        
        layout.addWidget(format_group)
        
        # 导出范围组
        range_group = QGroupBox("导出范围")
        range_layout = QVBoxLayout(range_group)
        
        # 范围选择
        self.export_latest_radio = QRadioButton("导出最新样本")
        self.export_latest_radio.setChecked(True)
        self.export_latest_radio.toggled.connect(self.on_export_range_changed)
        range_layout.addWidget(self.export_latest_radio)
        
        # 最新样本数量设置
        latest_count_layout = QHBoxLayout()
        latest_count_layout.addWidget(QLabel("数量:"), 0)  # 标签不拉伸，只占用必要空间
        self.latest_count_spinbox = QSpinBox()
        self.latest_count_spinbox.setRange(1, 10000)
        self.latest_count_spinbox.setValue(100)
        self.latest_count_spinbox.setSuffix(" 个")
        self.latest_count_spinbox.setEnabled(True)
        latest_count_layout.addWidget(self.latest_count_spinbox)
        latest_count_layout.addStretch()
        range_layout.addLayout(latest_count_layout)
        
        self.export_time_range_radio = QRadioButton("按时间范围导出")
        self.export_time_range_radio.toggled.connect(self.on_export_range_changed)
        range_layout.addWidget(self.export_time_range_radio)

        # 起始时间
        start_time_layout = QHBoxLayout()
        start_time_layout.addWidget(QLabel("开始时间:"), 0)  # 标签不拉伸，只占用必要空间
        self.start_date_edit = QDateEdit()
        self.start_date_edit.setDate(datetime.now().date())
        self.start_date_edit.setCalendarPopup(True)
        self.start_date_edit.setEnabled(False)
        start_time_layout.addWidget(self.start_date_edit, 1)  # 日期控件拉伸，占用更多空间
        self.start_time_edit = QTimeEdit()
        self.start_time_edit.setTime(datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).time())
        self.start_time_edit.setDisplayFormat("HH:mm")
        self.start_time_edit.setEnabled(False)
        start_time_layout.addWidget(self.start_time_edit, 1)  # 时间控件拉伸，占用更多空间
        range_layout.addLayout(start_time_layout)

        # 结束时间
        end_time_layout = QHBoxLayout()
        end_time_layout.addWidget(QLabel("结束时间:"), 0)  # 标签不拉伸，只占用必要空间
        self.end_date_edit = QDateEdit()
        self.end_date_edit.setDate(datetime.now().date())
        self.end_date_edit.setCalendarPopup(True)
        self.end_date_edit.setEnabled(False)
        end_time_layout.addWidget(self.end_date_edit, 1)  # 日期控件拉伸，占用更多空间
        self.end_time_edit = QTimeEdit()
        self.end_time_edit.setTime(datetime.now().replace(hour=23, minute=59, second=0, microsecond=0).time())
        self.end_time_edit.setDisplayFormat("HH:mm")
        self.end_time_edit.setEnabled(False)
        end_time_layout.addWidget(self.end_time_edit, 1)  # 时间控件拉伸，占用更多空间
        range_layout.addLayout(end_time_layout)
        
        # 快捷时间选择按钮
        quick_time_layout = QHBoxLayout()
        quick_time_layout.addWidget(QLabel("快捷选择:"), 0)  # 标签不拉伸，只占用必要空间
        
        self.today_button = QPushButton("今天")
        self.today_button.setMaximumWidth(60)
        self.today_button.clicked.connect(self.set_today_range)
        self.today_button.setEnabled(False)
        quick_time_layout.addWidget(self.today_button)
        
        self.yesterday_button = QPushButton("昨天")
        self.yesterday_button.setMaximumWidth(60)
        self.yesterday_button.clicked.connect(self.set_yesterday_range)
        self.yesterday_button.setEnabled(False)
        quick_time_layout.addWidget(self.yesterday_button)
        
        self.last_7_days_button = QPushButton("最近7天")
        self.last_7_days_button.setMaximumWidth(80)
        self.last_7_days_button.clicked.connect(self.set_last_7_days_range)
        self.last_7_days_button.setEnabled(False)
        quick_time_layout.addWidget(self.last_7_days_button)
        
        self.last_30_days_button = QPushButton("最近30天")
        self.last_30_days_button.setMaximumWidth(80)
        self.last_30_days_button.clicked.connect(self.set_last_30_days_range)
        self.last_30_days_button.setEnabled(False)
        quick_time_layout.addWidget(self.last_30_days_button)
        
        quick_time_layout.addStretch()
        range_layout.addLayout(quick_time_layout)
        
        self.export_all_radio = QRadioButton("导出全部样本")
        self.export_all_radio.toggled.connect(self.on_export_range_changed)
        range_layout.addWidget(self.export_all_radio)
        
        self.export_current_page_radio = QRadioButton("仅导出当前页样本")
        self.export_current_page_radio.toggled.connect(self.on_export_range_changed)
        range_layout.addWidget(self.export_current_page_radio)
        
        self.export_selected_radio = QRadioButton("仅导出选中样本")
        self.export_selected_radio.toggled.connect(self.on_export_range_changed)
        range_layout.addWidget(self.export_selected_radio)
        
        # 更新选中样本数量显示
        self.update_selected_count()
        
        layout.addWidget(range_group)
        
        # 连接数量变化信号
        self.latest_count_spinbox.valueChanged.connect(self.on_latest_count_changed)
        
        # Excel特有选项（仅在选择Excel格式时显示）
        self.excel_options_group = QGroupBox("Excel导出选项")
        excel_options_layout = QVBoxLayout(self.excel_options_group)
        
        self.include_all_data_checkbox = QCheckBox("包含所有检测数据（HbA1c、LA1c、HbA0、eAG、A2、HbE、HbD、HbS、HbC、p3、v-win等）")
        self.include_all_data_checkbox.setChecked(True)
        excel_options_layout.addWidget(self.include_all_data_checkbox)
        
        layout.addWidget(self.excel_options_group)
        
        # 导出按钮
        button_layout = QHBoxLayout()
        
        self.export_button = QPushButton("开始导出")
        self.export_button.clicked.connect(self.start_export)
        self.export_button.setMinimumHeight(40)
        button_layout.addWidget(self.export_button)
        
        self.cancel_button = QPushButton("取消")
        self.cancel_button.clicked.connect(self.reject)
        self.cancel_button.setMinimumHeight(40)
        button_layout.addWidget(self.cancel_button)
        
        layout.addLayout(button_layout)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setVisible(False)
        layout.addWidget(self.progress_bar)
        
        # 状态标签
        self.status_label = QLabel("请选择导出选项")
        self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.status_label.setStyleSheet("color: #666; font-size: 12px;")
        layout.addWidget(self.status_label)
        
        # 初始化导出范围选择状态
        self.on_export_range_changed()
        self.on_export_format_changed()
    
    def update_selected_count(self):
        """更新选中样本数量显示"""
        selected_count = len(self.selected_samples)
        if selected_count > 0:
            self.export_selected_radio.setText(f"仅导出选中样本 ({selected_count}个)")
            self.export_selected_radio.setEnabled(True)
        else:
            self.export_selected_radio.setText("仅导出选中样本 (无选中)")
            self.export_selected_radio.setEnabled(False)
            if self.export_selected_radio.isChecked():
                self.export_latest_radio.setChecked(True)
    
    def on_latest_count_changed(self):
        """最新样本数量改变事件"""
        if self.export_latest_radio.isChecked():
            count = self.latest_count_spinbox.value()
            self.status_label.setText(f"将导出最新的 {count} 个样本")
    
    def set_today_range(self):
        """设置今天的时间范围"""
        today = datetime.now().date()
        self.start_date_edit.setDate(today)
        self.start_time_edit.setTime(datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).time())
        self.end_date_edit.setDate(today)
        self.end_time_edit.setTime(datetime.now().replace(hour=23, minute=59, second=0, microsecond=0).time())
        self.on_export_range_changed()
    
    def set_yesterday_range(self):
        """设置昨天的时间范围"""
        yesterday = datetime.now().date() - timedelta(days=1)
        self.start_date_edit.setDate(yesterday)
        self.start_time_edit.setTime(datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).time())
        self.end_date_edit.setDate(yesterday)
        self.end_time_edit.setTime(datetime.now().replace(hour=23, minute=59, second=0, microsecond=0).time())
        self.on_export_range_changed()
    
    def set_last_7_days_range(self):
        """设置最近7天的时间范围"""
        end_date = datetime.now().date()
        start_date = end_date - timedelta(days=6)  # 包含今天，所以是6天前
        self.start_date_edit.setDate(start_date)
        self.start_time_edit.setTime(datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).time())
        self.end_date_edit.setDate(end_date)
        self.end_time_edit.setTime(datetime.now().replace(hour=23, minute=59, second=0, microsecond=0).time())
        self.on_export_range_changed()
    
    def set_last_30_days_range(self):
        """设置最近30天的时间范围"""
        end_date = datetime.now().date()
        start_date = end_date - timedelta(days=29)  # 包含今天，所以是29天前
        self.start_date_edit.setDate(start_date)
        self.start_time_edit.setTime(datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).time())
        self.end_date_edit.setDate(end_date)
        self.end_time_edit.setTime(datetime.now().replace(hour=23, minute=59, second=0, microsecond=0).time())
        self.on_export_range_changed()
    
    def on_export_format_changed(self):
        """导出格式改变事件"""
        if self.excel_radio.isChecked():
            self.excel_options_group.setVisible(True)
            self.status_label.setText("Excel格式：将样本数据导出到Excel文件")
        else:
            self.excel_options_group.setVisible(False)
            self.status_label.setText("PDF格式：每条样本生成独立PDF文件，打包成ZIP压缩文件")
    
    def on_export_range_changed(self):
        """导出范围改变事件"""
        # 启用/禁用相关控件
        self.latest_count_spinbox.setEnabled(self.export_latest_radio.isChecked())
        
        time_range_enabled = self.export_time_range_radio.isChecked()
        self.start_date_edit.setEnabled(time_range_enabled)
        self.start_time_edit.setEnabled(time_range_enabled)
        self.end_date_edit.setEnabled(time_range_enabled)
        self.end_time_edit.setEnabled(time_range_enabled)
        self.today_button.setEnabled(time_range_enabled)
        self.yesterday_button.setEnabled(time_range_enabled)
        self.last_7_days_button.setEnabled(time_range_enabled)
        self.last_30_days_button.setEnabled(time_range_enabled)
        
        # 更新状态标签
        if self.export_latest_radio.isChecked():
            count = self.latest_count_spinbox.value()
            self.status_label.setText(f"将导出最新的 {count} 个样本")
        elif self.export_time_range_radio.isChecked():
            start_date = self.start_date_edit.date().toPyDate()
            start_time = self.start_time_edit.time().toPyTime()
            end_date = self.end_date_edit.date().toPyDate()
            end_time = self.end_time_edit.time().toPyTime()
            self.status_label.setText(f"将导出 {start_date} {start_time.strftime('%H:%M')} 至 {end_date} {end_time.strftime('%H:%M')} 时间段的样本")
        elif self.export_all_radio.isChecked():
            sample_count = len(self.samples)
            self.status_label.setText(f"将导出全部 {sample_count} 个样本")
        elif self.export_current_page_radio.isChecked():
            sample_count = len(self.current_page_samples)
            self.status_label.setText(f"将导出当前页 {sample_count} 个样本")
        elif self.export_selected_radio.isChecked():
            sample_count = len(self.selected_samples)
            if sample_count > 0:
                self.status_label.setText(f"将导出选中的 {sample_count} 个样本")
            else:
                self.status_label.setText("没有选中的样本")
    
    def load_hospital_info(self):
        """加载医院信息"""
        try:
            # 这里可以从数据库或配置文件加载医院信息
            # 暂时使用默认值
            self.export_manager.set_hospital_info(
                name="小苏科技",
                address="医院地址",
                contact="联系方式"
            )
        except Exception as e:
            logger.error(f"加载医院信息失败: {e}")
    
    def start_export(self):
        """开始导出"""
        try:
            # 获取导出范围
            if self.export_latest_radio.isChecked():
                count = self.latest_count_spinbox.value()
                # 按接收时间排序，获取最新的样本
                sorted_samples = sorted(self.samples, key=lambda x: x.receive_time, reverse=True)
                export_samples = sorted_samples[:count]
                range_name = f"最新{count}个样本"
            elif self.export_time_range_radio.isChecked():
                start_date = self.start_date_edit.date().toPyDate()
                start_time = self.start_time_edit.time().toPyTime()
                end_date = self.end_date_edit.date().toPyDate()
                end_time = self.end_time_edit.time().toPyTime()
                
                # 组合完整的开始和结束时间
                start_datetime = datetime.combine(start_date, start_time)
                end_datetime = datetime.combine(end_date, end_time)
                
                # 筛选时间范围内的样本
                export_samples = []
                for sample in self.samples:
                    try:
                        # 优先使用样本分析时间
                        if hasattr(sample.sample_info, 'datetime') and sample.sample_info.datetime:
                            sample_datetime = datetime.strptime(sample.sample_info.datetime, "%Y-%m-%d %H:%M:%S")
                            if start_datetime <= sample_datetime <= end_datetime:
                                export_samples.append(sample)
                    except:
                        # 备用方案：使用接收时间
                        try:
                            sample_datetime = sample.receive_time
                            if start_datetime <= sample_datetime <= end_datetime:
                                export_samples.append(sample)
                        except:
                            continue
                
                range_name = f"{start_date} {start_time.strftime('%H:%M')}至{end_date} {end_time.strftime('%H:%M')}时间段样本"
            elif self.export_all_radio.isChecked():
                export_samples = self.samples
                range_name = "全部样本"
            elif self.export_current_page_radio.isChecked():
                export_samples = self.current_page_samples
                range_name = "当前页样本"
            elif self.export_selected_radio.isChecked():
                export_samples = self.selected_samples
                range_name = "选中样本"
            else:
                QMessageBox.warning(self, "警告", "请选择导出范围")
                return
            
            if not export_samples:
                QMessageBox.warning(self, "警告", "没有样本数据可导出")
                return
            
            # 获取导出格式
            if self.excel_radio.isChecked():
                export_format = "excel"
                file_filter = "Excel文件 (*.xlsx)"
                default_ext = ".xlsx"
            else:
                export_format = "pdf"
                file_filter = "ZIP压缩文件 (*.zip)"
                default_ext = ".zip"
            
            # 选择保存路径
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            if export_format == "excel":
                default_filename = f"样本数据_{timestamp}.xlsx"
            else:
                default_filename = f"样本数据_{timestamp}.zip"
            
            file_path, _ = QFileDialog.getSaveFileName(
                self, "保存导出文件", default_filename, file_filter
            )
            
            if not file_path:
                return
            
            # 确保文件扩展名正确
            if not file_path.endswith(default_ext):
                file_path += default_ext
            
            # 开始导出
            self.export_button.setEnabled(False)
            self.progress_bar.setVisible(True)
            self.progress_bar.setValue(0)
            self.status_label.setText(f"正在导出{range_name}...")
            
            # 创建导出工作线程
            self.export_worker = ExportWorker(
                export_manager=self.export_manager,
                samples=export_samples,
                file_path=file_path,
                export_format=export_format,
                include_all_data=self.include_all_data_checkbox.isChecked() if export_format == "excel" else True
            )
            
            # 连接信号
            self.export_worker.progress_updated.connect(self.progress_bar.setValue)
            self.export_worker.export_completed.connect(self.on_export_completed)
            
            # 启动线程
            self.export_worker.start()
            
        except Exception as e:
            logger.error(f"开始导出失败: {e}")
            QMessageBox.critical(self, "错误", f"开始导出失败: {e}")
            self.reset_export_ui()
    
    def on_export_completed(self, success: bool, message: str):
        """导出完成回调"""
        try:
            if success:
                QMessageBox.information(self, "导出成功", message)
                self.accept()  # 关闭对话框
            else:
                QMessageBox.critical(self, "导出失败", message)
                self.reset_export_ui()
        except Exception as e:
            logger.error(f"处理导出完成回调失败: {e}")
            self.reset_export_ui()
    
    def reset_export_ui(self):
        """重置导出UI状态"""
        self.export_button.setEnabled(True)
        self.progress_bar.setVisible(False)
        self.status_label.setText("请选择导出选项")
        
        if self.export_worker:
            self.export_worker.quit()
            self.export_worker.wait()
            self.export_worker = None
    
    def closeEvent(self, event):
        """关闭事件"""
        if self.export_worker and self.export_worker.isRunning():
            reply = QMessageBox.question(
                self, "确认关闭", 
                "导出正在进行中，确定要关闭吗？",
                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
            )
            
            if reply == QMessageBox.StandardButton.Yes:
                self.reset_export_ui()
                event.accept()
            else:
                event.ignore()
        else:
            event.accept()
